#include<iostream>
#include<pthread.h>
#include<string.h>
#include<functional>
using namespace std;


class thread;//声明
class Context
{
 public:
 thread* _this;//this指针
 void* _args;//函数参数
 public:
 Context()
 :_this(nullptr)
 ,_args(nullptr)
 {}
 ~Context()
 {}
};

class thread
{
public:
typedef  function<void* (void*)> func_t;//包装器构建返回值类型为void* 参数类型为void* 的函数类型
const int num=1024;
 thread(func_t func,void* args,int number=0)//构造函数
 : fun_(func)
 ,args_(args)
 {
char namebuffer[num];
snprintf(namebuffer,sizeof namebuffer,"threa--%d",number);//缓冲区内保存线程的名字即几号线程
Context* ctx=new Context();//
ctx->_this=this;
ctx->_args=args_;
int n=pthread_create(&pid_,nullptr,start_rontine,ctx);//因为调用函数start_rontine是类内函数，具有缺省参数this指针，在后续解包参数包会出问题，所以需要一个类来直接获取函数参数
assert(n==0);
(void)n;
 }

static void* start_rontine(void* args)
{
Context* ctx=static_cast<Context*>(args);
void *ret= ctx->_this->run(ctx->_args);//调用外部函数
delete ctx;
return ret;
}
void* run(void* args)
{
    return fun_(args);//调用外部函数
}
void join()
{
  int n=  pthread_join(pid_,nullptr);
  assert(n==0);
  (void)n;
}
~thread()
{
    //
}

    private:
    string name_;//线程的名字
    pthread_t pid_;//线程id
  func_t fun_;//线程调用的函数对象
  void* args_;//线程调用的函数的参数
};





// class thread;//声明 
// class Context
// {
//     public:
//     thread* this_;
//     void* args_;
// public:
//     Context()
//     :this_(nullptr)
//     ,args_(nullptr)
// {}
// ~Context()
// {}

// };
// class thread
// {
// public:
// typedef function<void* (void*)>fun_t;
// const int num=1024;
// public:
// thread(fun_t func,void* args=nullptr,int number=0)//构造函数,func是外部传进来的方法，args是外部传进来的方法参数，number是线程的编号
// :func_(func)
// ,args_(args)
// {
// char buffer[num];//建立缓存区
// snprintf(buffer,sizeof buffer,"thread--%d",number);
// name_=buffer;

// Context* ctx=new Context();
// ctx->this_=this;
// ctx->args_=args_;
// int n=pthread_create(&pid_,nullptr,start_routine,ctx);
// assert(n==0);
// (void)n;
// }

// static void* start_routine(void* args)//线程运用的方法。这里用静态修饰，原因在于这里的参数还有一个隐藏的this指针，在后续的转化会出问题
// {
// Context* ctx=static_cast<Context*>(args);
// void* ret=ctx->this_->run(ctx->args_);//把方法的参数传给外面那层方法并把返回值用ret记录。这这里要调用外部类来协助传参，因为静态函数只能调用静态函数。所以借助外部类中成员来传参
// delete ctx;
// return ret;
// }

// void join()//线程的回收
// {
// int n=pthread_join(pid_,nullptr);
// assert(n==0);
// (void)n;
// }

// void * run(void* args)
// {
//     return func_(args);//把参数传给外面那层的方法并把返回值返回
// }

// ~thread()//线程的析构
// {
//     //nothing
// }

// private:
// string name_;//线程的名字
// fun_t func_;//线程的方法
// void* args_;//线程方法的参数
// pthread_t pid_;//线程的id

// };
